package com.hschinese.pronunciation.task;

import android.annotation.TargetApi;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.content.DialogInterface.OnClickListener;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Environment;
import android.view.KeyEvent;


import com.hschinese.pronunciation.R;
import com.hschinese.pronunciation.activity.MyApplication;
import com.hschinese.pronunciation.interfaces.Actions;
import com.hschinese.pronunciation.utils.Constant;
import com.hschinese.pronunciation.utils.ThreadPoolUtil;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.LinkedList;

/**
 * 必须是实现了Action接口的Activity才可以使用该方法
 */
public class DownloadNewVersionTask extends AsyncTask<String, Integer, Long> {
	private ProgressDialog mDialog;
	private boolean notCanceled = true;  //是否取消
	private String destination;
	private Context mContext;
	private String fileName = "Pronunciation.apk";
	private boolean isNotCanceled;
	public DownloadNewVersionTask(Context context, final boolean isNotCanceled){
        mContext = context;
		mDialog = new ProgressDialog(context);
		mDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
		mDialog.setProgress(0);
        mDialog.setMax(1);
        mDialog.setCanceledOnTouchOutside(false);
        mDialog.setButton(ProgressDialog.BUTTON_NEGATIVE, isNotCanceled?context.getString(R.string.setting_exit):context.getString(R.string.btn_cancel), new OnClickListener() {

		@Override
		public void onClick(DialogInterface dialog, int which) {
			mDialog.cancel();
			notCanceled = false;
			if(isNotCanceled){
				ThreadPoolUtil.getInstance().shutdownNow();
				LinkedList<Activity> allAtys = MyApplication.getInstance().getAllAtys();
				for (Activity activity : allAtys) {
					activity.finish();
				}
				android.os.Process.killProcess(android.os.Process.myPid());
			}
		}
		});
        mDialog.setOnCancelListener(new OnCancelListener() {
            @Override
            public void onCancel(DialogInterface dialog) {
                 cancel(true);
                 notCanceled = false;
                 ((Actions)mContext).installNewVersion(-1L, null);
            }
        });
		if(isNotCanceled){
			mDialog.setCancelable(false);
			mDialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
				@Override
				public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
					return true;
				}
			});
		}
		destination = Environment.getExternalStorageDirectory().getAbsolutePath()+ Constant.RELATIVE_EXTERNAL_DATA_PATH+"temp/";
	}

	@Override
	protected void onPreExecute() {
      //先判断文件是否存在
	  File file = new File(destination);
	  if(file.exists()){  //文件存在时删除
		file.delete();
	  }
	  if(mDialog!=null){
        setNumberFormat();  // 设置状态数字格式api11及以上的才会设置
        mDialog.show();
      }
	}

	@Override
	protected Long doInBackground(String... params) {
		if(isCancelled()){
			return 0L;
		}
        long totalSize = downloadFile(params[0]);  //下载文件
        return totalSize;
	}


	@Override
	protected void onPostExecute(Long result) {
		if(mDialog!=null && mDialog.isShowing()){
			mDialog.dismiss();
			mDialog = null;
		}
		if(result <= 0){
			new File(destination).delete();   //删除已经创建的文件
		}
		if(isCancelled()){
			return;
		}
		((Actions)mContext).installNewVersion(result, destination+fileName);
	}

	@Override
	protected void onCancelled() {
			File file = new File(destination);
		if(file.exists()){
			file.delete();
			file = null;
		}
		super.onCancelled();
	}


	@Override
	protected void onProgressUpdate(Integer... values) {
	    if(mDialog==null)
	          return;
        if(values.length>1){
         int contentLength = values[1];
         if(contentLength==-1){
             mDialog.setIndeterminate(true);
         }
        } else{
            mDialog.setProgress(values[0].intValue());
        }
	}

	/**
	 * 下载文件
	 * @param url 下载url
	 * @return
	 */
	private long downloadFile(String url){
        URLConnection connection = null;
        int bytesCopied = 0;
		File folder = new File(destination);
		try {
			URL mUrl = new URL(url); //
			connection = mUrl.openConnection();
			int fileLength = connection.getContentLength();
			if (fileLength != -1) {
				if (!folder.exists()) {
					folder.mkdirs();
				}
				mDialog.setMax(fileLength / 1024);  //单位 kb
				OutputStream oStream = new FileOutputStream(destination + fileName);
				publishProgress(0, fileLength);
				bytesCopied = copy(connection.getInputStream(), oStream);  //生成文件
			}
		} catch (IOException e) {
			e.printStackTrace();
			bytesCopied = 0;
		}
		return bytesCopied;
	}



	/**
	 * 将文件输出到目录中
	 * @param input
	 * @param output
	 * @return
	 */
    private int copy(InputStream input, OutputStream output) throws IOException {
        byte[] buffer = new byte[1024*8];
        BufferedInputStream in = new BufferedInputStream(input, 1024*8);
        BufferedOutputStream out  = new BufferedOutputStream(output, 1024*8);
        int count=0,n=0;
        try {
            while(notCanceled && (n=in.read(buffer, 0, 1024*8))!=-1){
                out.write(buffer, 0, n);
                count+=n;
                publishProgress(count/1024);
            }
            out.flush();
        } catch (IOException e) {
        	count = 0;  //发生异常，将已经下载的数据长度设为0
            throw e;  //发生异常则将异常抛出
        }finally{
            try {
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return count;
    }

	/**
	 * 设置格式内容，只有api>=11的时候可以
	 */
	@TargetApi(Build.VERSION_CODES.HONEYCOMB)
	private void setNumberFormat(){
	  if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB){
        	mDialog.setProgressNumberFormat("%1d kb/%2d kb");
      }
	}
    
}
